{
  "nbformat": 4,
  "nbformat_minor": 5,
  "metadata": {},
  "cells": [
    {
      "metadata": {},
      "source": [
        "<td>\n",
        "   <a target=\"_blank\" href=\"https://labelbox.com\" ><img src=\"https://labelbox.com/blog/content/images/2021/02/logo-v4.svg\" width=256/></a>\n",
        "</td>"
      ],
      "cell_type": "markdown"
    },
    {
      "metadata": {},
      "source": [
        "<td>\n",
        "<a href=\"https://colab.research.google.com/github/Labelbox/labelbox-python/blob/master/examples/basics/user_management.ipynb\" target=\"_blank\"><img\n",
        "src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"></a>\n",
        "</td>\n",
        "\n",
        "<td>\n",
        "<a href=\"https://github.com/Labelbox/labelbox-python/tree/master/examples/basics/user_management.ipynb\" target=\"_blank\"><img\n",
        "src=\"https://img.shields.io/badge/GitHub-100000?logo=github&logoColor=white\" alt=\"GitHub\"></a>\n",
        "</td>"
      ],
      "cell_type": "markdown"
    },
    {
      "metadata": {},
      "source": [
        "# User Management\n",
        "* This notebook covers the following:\n",
        "    * create invites\n",
        "    * query for remaining allowed invites to an organization\n",
        "    * set and update organization roles\n",
        "    * assign users to projects\n",
        "        * set / update / revoke project role\n",
        "    * delete users from org"
      ],
      "cell_type": "markdown"
    },
    {
      "metadata": {},
      "source": [
        "!pip install labelbox"
      ],
      "cell_type": "code",
      "outputs": [],
      "execution_count": null
    },
    {
      "metadata": {},
      "source": [
        "import labelbox as lb\n",
        "import os"
      ],
      "cell_type": "code",
      "outputs": [],
      "execution_count": null
    },
    {
      "metadata": {},
      "source": [
        "* You have to specifically enable experimental features to use this functionality. Notice the \n",
        "`enable_experimental = True`\n",
        "    * enables users to send invites and checking the number of seats available via the sdk"
      ],
      "cell_type": "markdown"
    },
    {
      "metadata": {},
      "source": [
        "# API Key and Client\n",
        "Provide a valid api key below in order to properly connect to the Labelbox Client."
      ],
      "cell_type": "markdown"
    },
    {
      "metadata": {},
      "source": [
        "# Add your api key\n",
        "API_KEY = None\n",
        "client = lb.Client(api_key=API_KEY, enable_experimental=True)\n",
        "organization = client.get_organization()"
      ],
      "cell_type": "code",
      "outputs": [],
      "execution_count": null
    },
    {
      "metadata": {},
      "source": [
        "# Please provide a dummy email here:\n",
        "# Preferrably one you can access. If you have a google account you can do email+1@<domain>.com\n",
        "DUMMY_EMAIL = \"SET THIS\"\n",
        "# This should be set to an account that you wan't to change the permissions for.\n",
        "# You could invite a new user, accept the invite and use that account if you don't want to effect any active users\n",
        "DUMMY_USER_ACCOUNT_ID = \"ckneh4n8c9qvq0706uwwg5i16\""
      ],
      "cell_type": "code",
      "outputs": [],
      "execution_count": null
    },
    {
      "metadata": {},
      "source": [
        "### Roles\n",
        "* When inviting a new user to an organization, there are various roles to select from.\n",
        "* All available roles to your org can be accessed via `client.get_roles()`"
      ],
      "cell_type": "markdown"
    },
    {
      "metadata": {},
      "source": [
        "roles = client.get_roles()\n",
        "for name, role in roles.items():\n",
        "    print(role.name, \":\", role.uid)"
      ],
      "cell_type": "code",
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "LABELER : cjlvi914y1aa20714372uvzjv\n",
            "REVIEWER : cjlvi919b1aa50714k75euii5\n",
            "TEAM_MANAGER : cjlvi919q1aa80714b7z3xuku\n",
            "ADMIN : cjlvi91a41aab0714677xp87h\n",
            "NONE : cjmb6xy80f5vz0780u3mw2rj4\n"
          ]
        }
      ],
      "execution_count": null
    },
    {
      "metadata": {},
      "source": [
        "* Above we printed out all of the roles available to the current org.\n",
        "* Notice the `NONE`. That is for project level roles"
      ],
      "cell_type": "markdown"
    },
    {
      "metadata": {},
      "source": [
        "### Create\n",
        "* Users are created by sending an invite\n",
        "* An email will be sent to them and they will be asked to join your organization"
      ],
      "cell_type": "markdown"
    },
    {
      "metadata": {},
      "source": [
        "#### Organization Level Permissions\n",
        "* Invite a new labeler with labeling permissions on all projects"
      ],
      "cell_type": "markdown"
    },
    {
      "metadata": {},
      "source": [
        "# First make sure that you have enough seats:\n",
        "organization.invite_limit()"
      ],
      "cell_type": "code",
      "outputs": [
        {
          "data": {
            "text/plain": [
              "InviteLimit(remaining=2, used=3, limit=5)"
            ]
          },
          "execution_count": 6,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "execution_count": null
    },
    {
      "metadata": {},
      "source": [
        "invite = organization.invite_user(DUMMY_EMAIL, roles[\"LABELER\"])"
      ],
      "cell_type": "code",
      "outputs": [],
      "execution_count": null
    },
    {
      "metadata": {},
      "source": [
        "print(invite.created_at)\n",
        "print(invite.organization_role_name)\n",
        "print(invite.email)"
      ],
      "cell_type": "code",
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "2021-04-20 22:11:55.897000+00:00\n",
            "Labeler\n",
            "< SET THIS >\n"
          ]
        }
      ],
      "execution_count": null
    },
    {
      "metadata": {},
      "source": [
        "#### Project Level Permissions\n",
        "* Invite a new labeler with labeling permissions specific to a set of projects\n",
        "* Here we set organization level permissions to Roles.NONE to indicate that the user only has project level permissions"
      ],
      "cell_type": "markdown"
    },
    {
      "metadata": {},
      "source": [
        "project = client.create_project(name=\"test_user_management\", media_type=lb.MediaType.Image)\n",
        "project_role = lb.ProjectRole(project=project, role=roles[\"REVIEWER\"])\n",
        "invite = organization.invite_user(DUMMY_EMAIL,\n",
        "                                  roles[\"NONE\"],\n",
        "                                  project_roles=[project_role])"
      ],
      "cell_type": "code",
      "outputs": [],
      "execution_count": null
    },
    {
      "metadata": {},
      "source": [
        "### Read\n",
        "* Outstanding invites cannot be queried for at this time. This information can be found in the members tab of the web app.\n",
        "* You are able to query for members once they have joined."
      ],
      "cell_type": "markdown"
    },
    {
      "metadata": {},
      "source": [
        "users = list(organization.users())\n",
        "print(users[0])"
      ],
      "cell_type": "code",
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "<User {'created_at': datetime.datetime(2021, 1, 20, 1, 2, 31, tzinfo=datetime.timezone.utc), 'email': 'msokoloff@labelbox.com', 'intercom_hash': '050b8b292bd66abf88ea9a279c6ee80a530e0f9cf98a06e1d5372ef13697f46b', 'is_external_user': False, 'is_viewer': True, 'nickname': 'msokoloff', 'name': 'Matt Sokoloff', 'picture': 'https://lh6.googleusercontent.com/-gO94Mcw4PGs/AAAAAAAAAAI/AAAAAAAAAAA/AMZuuclv_5P5WICzV1aImhxGADj_OS5c7w/s96-c/photo.jpg', 'uid': 'ckk4q1vgwc0vp0704xhx7m4vk', 'updated_at': datetime.datetime(2021, 4, 1, 15, 48, 27, tzinfo=datetime.timezone.utc)}>\n"
          ]
        }
      ],
      "execution_count": null
    },
    {
      "metadata": {},
      "source": [
        "### Update\n",
        "* There is no update on invites. Instead you must delete and resend them\n",
        "* You can update User roles"
      ],
      "cell_type": "markdown"
    },
    {
      "metadata": {},
      "source": [
        "user = client._get_single(lb.User, DUMMY_USER_ACCOUNT_ID)\n",
        "\n",
        "# Give the user organization level permissions\n",
        "user.update_org_role(roles[\"LABELER\"])\n",
        "print(user.org_role())\n",
        "# Restore project level permissions\n",
        "user.update_org_role(roles[\"NONE\"])\n",
        "print(user.org_role())\n",
        "# Make the user a labeler for the current project\n",
        "user.upsert_project_role(project, roles[\"LABELER\"])\n",
        "print(user.org_role())"
      ],
      "cell_type": "code",
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "<OrgRole {'name': 'Labeler', 'uid': 'cjlvi914y1aa20714372uvzjv'}>\n",
            "<OrgRole {'name': 'None', 'uid': 'cjmb6xy80f5vz0780u3mw2rj4'}>\n",
            "<OrgRole {'name': 'None', 'uid': 'cjmb6xy80f5vz0780u3mw2rj4'}>\n"
          ]
        }
      ],
      "execution_count": null
    },
    {
      "metadata": {},
      "source": [
        "# Remove the user from a project (Same as setting the project role to `roles.NONE`)\n",
        "user.remove_from_project(project)"
      ],
      "cell_type": "code",
      "outputs": [],
      "execution_count": null
    },
    {
      "metadata": {},
      "source": [
        "### Delete"
      ],
      "cell_type": "markdown"
    },
    {
      "metadata": {},
      "source": [
        "* Invites can only be deleted from the ui at this time. \n",
        "* Deleting invites can be done in the members tab of the web app."
      ],
      "cell_type": "markdown"
    },
    {
      "metadata": {},
      "source": [
        "* Delete the User\n",
        "* Make sure you want to remove the user from the org:\n",
        "* `>>> organization.remove_user(user)`"
      ],
      "cell_type": "markdown"
    },
    {
      "metadata": {},
      "source": [
        "### Cleanup\n",
        "* We created an extra project. Let's delete it"
      ],
      "cell_type": "markdown"
    },
    {
      "metadata": {},
      "source": [
        "project.delete()"
      ],
      "cell_type": "code",
      "outputs": [],
      "execution_count": null
    }
  ]
}